package com.ia2011.project1.aima;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.ia2011.project1.debug.Debug;
import com.ia2011.project1.domain.Action;
import com.ia2011.project1.domain.Spot;
import com.ia2011.project1.domain.TAction;
import com.ia2011.project1.domain.User;
import com.ia2011.project1.service.CarpoolingService;

import aima.search.framework.Successor;
import aima.search.framework.SuccessorFunction;

public class CSSuccessorFunctionSA extends Debug implements SuccessorFunction {

	@Override
	public List getSuccessors(Object obj) {
		ArrayList successors = new ArrayList();
		CarpoolingService cs = (CarpoolingService) obj;
		
		Random rnd = new Random();
		
		int driver1Random = rnd.nextInt(cs.amountOfDrivers());
		int driver2Random;
		do {
			driver2Random = rnd.nextInt(cs.amountOfDrivers());
		} while (driver1Random == driver2Random);
		
		
		CarpoolingService newCarpoolingService = new CarpoolingService(cs);
		
		User driver1 = null;
		User driver2 = null;
		
		int counter = 0;
		for (int i=0; i<newCarpoolingService.getUsers().size(); i++) {
			if (newCarpoolingService.getUsers().get(i).isDriver()) {
				if (driver1Random == counter) {
					driver1 = newCarpoolingService.getUsers().get(i);
				} else if (driver2Random == counter) {
					driver2 = newCarpoolingService.getUsers().get(i);
				}
				counter++;
			}			
		}
		
		Spot spot1 = null;
		Spot spot2 = null;
		
		if ((driver1.getTransport().getPlan().size() - 2 > 0)
				&& (driver2.getTransport().getPlan().size() - 2 > 0)) {
			int randomSpot1 = rnd.nextInt((driver1.getTransport().getPlan().size() - 2)/2);
			int randomSpot2 = rnd.nextInt((driver2.getTransport().getPlan().size() - 2)/2);

			
			counter = 0;
			boolean found1 = false;
			for(int i=1; i<driver1.getTransport().getPlan().size()-1 && !found1; i++) {
				Spot spot = driver1.getTransport().getPlan().get(i);
				if (spot.getAction().getType() == TAction.PICK_USER) {
					if (counter == randomSpot1) {
						spot1 = spot;
						found1 = true;
					}
					counter++;
				}
			}
			
			counter = 0;
			boolean found2 = false;
			for(int i=1; i<driver2.getTransport().getPlan().size()-1 && !found2; i++) {
				Spot spot = driver2.getTransport().getPlan().get(i);
				if (spot.getAction().getType() == TAction.PICK_USER) {
					if (counter == randomSpot2) {
						spot2 = spot;
						found2 = true;
					}
					counter++;
				}
			}
			
			Point point = spot1.getCoord();
			TAction type = spot1.getAction().getType();
			Integer userId = spot1.getAction().getUserId();
			
			spot1.setCoord(new Point(spot2.getCoord()));
			spot1.setAction(new Action(spot2.getAction().getType(), spot2.getAction().getUserId()));
			for (Spot spot : driver1.getTransport().getPlan()) {
				if (spot.getAction().getUserId() == userId) {
					spot.getAction().setUserId(spot2.getAction().getUserId()); // put for DROP_USER action the same userId of 2nd user
				}
			}
			
			spot2.setCoord(new Point(point));
			spot2.setAction(new Action(type, userId));
			for (Spot spot : driver2.getTransport().getPlan()) {
				if (spot.getAction().getUserId() == spot1.getAction().getUserId()) {
					spot.getAction().setUserId(userId);
				}
			}

			successors.add(new Successor("swap(driver1Id:" + driver1.getId() 
					+ ", driver2Id:" + driver2.getId()
					+ ", Spot1UserId(now Spot2):" + spot2.getAction().getUserId()
					+ ", Spot2UserId(now Spot1):" + spot1.getAction().getUserId(),
					newCarpoolingService));
			
		}
		
//		info("successors size="+successors.size());
		return successors;
	}

}
